using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using System.Collections.Generic;


namespace IQIGame.Onigao.Game
{
    public static class MsgAsyncAwaiterAll
    {
        private readonly static List<IMsgAsyncAwaiter> msgAsyncAwaiters = new();

        public static void AddMsgAsyncAwaiter(IMsgAsyncAwaiter msgAsyncAwaiter)
        {
            msgAsyncAwaiters.Add(msgAsyncAwaiter);
        }

        public static void ClearMsgAwait(int startId, int endId)
        {
            foreach (var item in msgAsyncAwaiters)
            {
                int msgId = item.GetMessageId();
                if (msgId >= startId && msgId <= endId)
                {
                    item.CancelMsgAwait();
                }
            }
        }

        /// <summary>
        /// 取消所有的等待任务
        /// </summary>
        public static void ClearAllMsgAwait()
        {
            foreach (var item in msgAsyncAwaiters)
            {
                item.CancelMsgAwait();
            }
        }
    }

    public interface IMsgAsyncAwaiter
    {
        public bool CancelMsgAwait();

        public int GetMessageId();
    }

    public class MsgAsyncAwaiter<T> : Singleton<MsgAsyncAwaiter<T>>, IMsgAsyncAwaiter where T : struct, IMessage
    {
        private AutoResetUniTaskCompletionSource<T> taskCompletionSource;

        private MsgAsyncAwaiter()
        {
            MsgAsyncAwaiterAll.AddMsgAsyncAwaiter(this);
        }

        /// <summary>
        /// 添加等待任务
        /// </summary>
        /// <returns></returns>
        public UniTask<T> AddMsgAwait()
        {
            if (taskCompletionSource != null)
            {
                LogGame.LogError($"Call AddMsgAwait already exist, type = {this.GetType()}");
                return UniTask.FromResult<T>(default);
            }

            taskCompletionSource = AutoResetUniTaskCompletionSource<T>.Create();
            return taskCompletionSource.Task;
        }

        /// <summary>
        /// 调用完成等待任务，传入数据
        /// </summary>
        /// <param name="data"></param>
        public void CompleteMsgAwait(ref T data)
        {
            if (taskCompletionSource == null)
            {
                LogGame.LogError($"Call CompleteMsgAwait no exist, type = {this.GetType()}");
                return;
            }
            var tmp = taskCompletionSource;
            taskCompletionSource = null;//需要在TrySetResult之前置空, 不然可能taskCompletionSource回池后继续被改变
            tmp.TrySetResult(data);
        }

        /// <summary>
        /// 取消等待任务
        /// </summary>
        public bool CancelMsgAwait()
        {
            if (taskCompletionSource == null)
            {
                return false;
            }
            var tmp = taskCompletionSource;
            taskCompletionSource = null;//需要在TrySetResult之前置空, 不然可能taskCompletionSource回池后继续被改变
            tmp.TrySetResult(default);
            return true;
        }

        private int _cache_messageId;
        public int GetMessageId()
        {
            if (_cache_messageId == 0)
            {
                T template = default;
                _cache_messageId = template.GetMessageId();
            }
            return _cache_messageId;
        }



    }
}
